package com.dkm.orproject.dkmoa.service.serviceimpl.flow;

import com.dkm.orproject.dkmoa.dao.*;
import com.dkm.orproject.dkmoa.domain.*;
import com.dkm.orproject.dkmoa.service.flow.OaRegularFlowService;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName : OaRegularFlowServiceImpl  //类名
 * @Description : 转正流程服务接口实现类  //描述
 * @Author : 易嵘  //作者
 * @Date: 2020-10-10 14:12  //时间
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OaRegularFlowServiceImpl implements OaRegularFlowService {

    /**
     * 起草节点
     */
    static Long START_NODE = 765973878542577664L;

    /**
     * 人事部填写
     */
    static Long STAFFING_NODE= 766231433026088960L;

    /**
     * 部门审核节点id
     */
    static final Long AUDIT_SECTION_NODE = 766232160217739264L;


    /**
     * 人事审核节点id
     */
    static final Long AUDIT_STAFFING_NODE = 766232233324457984L;

    /**
     * 结束节点id
     */
    static final Long OVER_NODE = 766232301880356864L;

    /**
     * 人事填写权限
     */
    static final String STAFFING_WRITE="STAFFING_WRITE";

    /**
     * 人事审核
     */
    static final String REGULAR_STAFFING_CHECK_INFORM="REGULAR_STAFFING_CHECK_INFORM";

    /**
     * 流程记录
     */
    OaFlowSchedule flowSchedule;

    /**
     * 流程记录日志
     */
    @Resource
    OaFlowScheduleMapper flowScheduleMapper;

    /**
     * 部门Mapper
     */
    @Resource
    OaDepartmentMapper departmentMapper;

    /**
     * 通知人员关联Mapper
     */
    @Resource
    OaInformMapper informMapper;

    /**
     * 通知Mapper
     */
    @Resource
    OaMessageMapper messageMapper;

    /**
     * 转正流程Mapper
     */
    @Resource
    OaRegularFlowMapper regularFlowMapper;

    /**
     * 人员Mapper
     */
    @Resource
    OaPersonnelMapper personnelMapper;

    /**
     * id生成工具
     */
    @Resource
    IdToobtainUtils idToobtainUtils;


    /**
     * 分页查询所有（条件）
     * @param regularFlow 转正流程模型（条件查询）
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param page 当前页数
     * @param limit 显示行数
     * @return 查询结果
     */
    @Override
    public List<OaRegularFlow> findAll(String regularFlow, String startTime, String endTime, Integer page, Integer limit) {
        PageHelper.startPage(page,limit);
        return regularFlowMapper.findAll(regularFlow,startTime,endTime);
    }

    /**
     * 总行数
     * @param regularFlow 转正流程模型（条件查询）
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 查询结果
     */
    @Override
    public Long rowCount(String regularFlow, String startTime, String endTime) {
        return regularFlowMapper.rowCount(regularFlow,startTime,endTime);
    }

    /**
     * id查询
     * @param id 转正id
     * @return 查询结果
     */
    @Override
    public OaRegularFlow findById(Long id) {
        return regularFlowMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询所有
     * @param list id集合 根据id集合查询 id为空则查询所有
     * @return 查询结果
     */
    @Override
    public List<OaRegularFlow> selectAll(List<Long> list) {
        return regularFlowMapper.selectAll(list);
    }

    /**
     * 批量删除
     * @param list id集合 删除该集合的数据
     * @return 回调函数
     */
    @Override
    public int deleteAll(List<Long> list) {
        return regularFlowMapper.deleteAll(list);
    }

    /**
     * id删除
     * @param id 转正流程id
     * @return 回调函数
     */
    @Override
    public int deleteById(Long id) {
        return regularFlowMapper.deleteByPrimaryKey(id);
    }

    /**
     * 起草新增
     * @param flow 转正流程模型
     * @param personnelName 起草人名称
     * @return 回调函数
     */
    @Override
    public int add(OaRegularFlow flow, String personnelName) {
        OaPersonnel personnel=personnelMapper.selectByPrimaryKey(flow.getPersonnelId());

        //创建人
        flow.setCreatedBy(personnelName);
        //转正流程名称
        flow.setRegularName(personnel.getPersonnelName()+"的转正流程");
        // 设置为人事填写
        flow.setIsRevision("R");
        // 流程id 人事填写
        flow.setRegularSchedule(STAFFING_NODE);
        int row;
        //判断是新增还是修改
        if(ObjectUtils.isEmpty(flow.getPkRegularId())){
            //转正流程id
            flow.setPkRegularId(idToobtainUtils.getNumberId());
            row = regularFlowMapper.insertSelective(flow);
        }else{
            row = regularFlowMapper.updateByPrimaryKeySelective(flow);
        }

        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  起草节点
        flowSchedule.setFlowId(START_NODE);
        // 绑定表单
        flowSchedule.setFormId(flow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增转正流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(flow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(flow.getPkRegularId());
        // 通知标题
        message.setMessageName(flow.getRegularName()
        );
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 根据流程id查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(STAFFING_WRITE);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }
        return row;
    }

    /**
     * 人事填写
     * @param regularFlow 人事填写信息
     * @param personnel 操作人
     * @return 回调函数
     */
    @Override
    public int staffing(OaRegularFlow regularFlow, OaPersonnel personnel) {

        OaPersonnel oaPersonnel=personnelMapper.selectByPersonId(regularFlow.getPersonnelId());

        // 流程id 部门审核
        regularFlow.setRegularSchedule(AUDIT_SECTION_NODE);
        regularFlow.setIsRevision("D");
        int row = regularFlowMapper.updateByPrimaryKeySelective(regularFlow);
        regularFlow= regularFlowMapper.selectByPrimaryKey(regularFlow.getPkRegularId());
        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  人事填写
        flowSchedule.setFlowId(STAFFING_NODE);
        // 绑定表单
        flowSchedule.setFormId(regularFlow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(regularFlow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(regularFlow.getPkRegularId());
        // 通知标题
        message.setMessageName(regularFlow.getRegularName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //查询部门领导
        Long personnelId = departmentMapper.selectByPrimaryKey(oaPersonnel.getPkDepartmentId()).getPersonnelId();
        // 新建通知关联
        OaInform inform = new OaInform();
        // 通知关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 设置为未读
        inform.setIsState("0");
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 人员id
        inform.setPersonnelId(personnelId);

        // 新增通知关联集合
        informMapper.insertSelective(inform);
        return row;
    }

    /**
     * 部门通过
     * @param regularFlow 审核信息
     * @param personnel 操作人
     * @return 回调函数
     */
    @Override
    public int sectionPass(OaRegularFlow regularFlow, OaPersonnel personnel) {
        //设置为人事审核
        regularFlow.setIsRevision("C");
        // 流程id 人事审核
        regularFlow.setRegularSchedule(AUDIT_STAFFING_NODE);
        int row = regularFlowMapper.updateByPrimaryKeySelective(regularFlow);
        regularFlow= regularFlowMapper.selectByPrimaryKey(regularFlow.getPkRegularId());

        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  部门审核
        flowSchedule.setFlowId(AUDIT_SECTION_NODE);
        // 绑定表单
        flowSchedule.setFormId(regularFlow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(regularFlow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(regularFlow.getPkRegularId());
        // 通知标题
        message.setMessageName(regularFlow.getRegularName()
        );
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 根据通知权限代码查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(REGULAR_STAFFING_CHECK_INFORM);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }
        return row;
    }

    /**
     * 部门不通过
     * @param regularFlow 审核信息
     * @param personnel 操作人
     * @param formReason 不通过原因
     * @return 回调函数
     */
    @Override
    public int sectionNoPass(OaRegularFlow regularFlow, OaPersonnel personnel, String formReason) {
        //设置为人事审核
        regularFlow.setIsRevision("R");
        // 流程id 人事填写
        regularFlow.setRegularSchedule(STAFFING_NODE);
        int row = regularFlowMapper.updateByPrimaryKeySelective(regularFlow);
        regularFlow= regularFlowMapper.selectByPrimaryKey(regularFlow.getPkRegularId());

        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  部门审核
        flowSchedule.setFlowId(AUDIT_SECTION_NODE);
        // 绑定表单
        flowSchedule.setFormId(regularFlow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(regularFlow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(regularFlow.getPkRegularId());
        // 通知标题
        message.setMessageName(regularFlow.getRegularName()
        );
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 根据流程id查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(STAFFING_WRITE);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }

        return row;
    }

    /**
     * 人事通过
     * @param regularFlow 审核信息
     * @param personnel 操作人
     * @return 回调函数
     */
    @Override
    public int staffingPass(OaRegularFlow regularFlow, OaPersonnel personnel) {
        //设置为结束（有效）
        regularFlow.setIsRevision("1");
        // 流程id 结束节点
        regularFlow.setRegularSchedule(OVER_NODE);
        int row = regularFlowMapper.updateByPrimaryKeySelective(regularFlow);
        regularFlow= regularFlowMapper.selectByPrimaryKey(regularFlow.getPkRegularId());

        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  人事审核
        flowSchedule.setFlowId(AUDIT_STAFFING_NODE);
        // 绑定表单
        flowSchedule.setFormId(regularFlow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 通过原因
        flowSchedule.setFormReason("  ");
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  结束节点
        flowSchedule.setFlowId(OVER_NODE);
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(regularFlow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(regularFlow.getPkRegularId());
        // 通知标题
        message.setMessageName(regularFlow.getRegularName());
        //状态 4 已办
        message.setIsRevision("4");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?show=1&pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 新建通知关联
        OaInform inform = new OaInform();
        // 通知关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 设置为未读
        inform.setIsState("0");
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 人员id
        inform.setPersonnelId(regularFlow.getPersonnelId());
        // 新增通知关联集合
        informMapper.insertSelective(inform);
        return row;
    }

    @Override
    public OaRegularFlow isExist(OaPersonnel personnel) {
        return regularFlowMapper.isExist(personnel.getPkPersonnelId());
    }

    /**
     * 人事不通过
     * @param regularFlow 审核信息
     * @param personnel 操作人
     * @param formReason 不通过原因
     * @return 回调函数
     */
    @Override
    public int staffingNoPass(OaRegularFlow regularFlow, OaPersonnel personnel, String formReason) {
        //设置为人事审核
        regularFlow.setIsRevision("R");
        // 流程id 人事填写
        regularFlow.setRegularSchedule(STAFFING_NODE);
        int row = regularFlowMapper.updateByPrimaryKeySelective(regularFlow);
        regularFlow= regularFlowMapper.selectByPrimaryKey(regularFlow.getPkRegularId());

        // 流程记录
        flowSchedule = new OaFlowSchedule();
        // 流程记录id
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 离职流程id  部门审核
        flowSchedule.setFlowId(AUDIT_STAFFING_NODE);
        // 绑定表单
        flowSchedule.setFormId(regularFlow.getPkRegularId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 不通过原因
        flowSchedule.setFormReason(formReason);
        //审核人
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增离职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(regularFlow.getPkRegularId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(regularFlow.getPkRegularId());
        // 通知标题
        message.setMessageName(regularFlow.getRegularName()
        );
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/regular/regularAudit.html?pkRegularId=");
        // 新增通知
        messageMapper.insertSelective(message);

        // 根据流程id查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(STAFFING_WRITE);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }
        return row;
    }

}
